﻿using Core.Com;
using Reader.SFC.Models;
using Reader.SFC.SdkInit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace Reader.SFC.Forms
{
    public partial class FrmInit : Form
    {
        static byte deviceNo = 0;
        System.Windows.Forms.Timer timerConnect = new Timer();
        // 负责连接设备的委托
        public delegate void DeleConnectDev(byte[] ip, int CommPort, int PortOrBaudRate);
        public FrmInit()
        {
            InitializeComponent();
        }
        public Dis.HANDLE_FUN f = new Dis.HANDLE_FUN(HandleData); //连续读卡
                                                                  //2016.11.3 ZW  数据产生时，触发此事件，更新ListView控件
        public delegate void UpdateControlEventHandlers();
        public static event UpdateControlEventHandlers UpdateControls;
        // 回调函数
        static string epc;
        public static void HandleData(IntPtr pData, int length)
        {
            epc = "";
            byte[] data = new byte[128];
            Marshal.Copy(pData, data, 0, length);
            for (int i = 1; i < length - 2; ++i)
            {
                epc += string.Format("{0:X2} ", data[i]);
            }
            $"扫描的EPC={epc}".Log();
            UpdateControls?.Invoke();


        }
        private void UdpTextEPC()
        {
            UpdateUI.UpdateUIControl(txtEpc, () =>
            {
                rlog.LogError($"扫描的EPC={epc}");
                var epcs = epc.Replace(" ", "").Substring(2);
                if (rad16.Checked && epcs.Length == config.FixEPCLen16)
                    txtEpc.Text = epcs;
                else if (rad24.Checked && epcs.Length == config.ProEPCLen24)
                    txtEpc.Text = epcs;
                else
                {
                    txtEpc.Text = "";
                    SetState(lblUpd);
                    rlog.LogError("标签EPC长度不符!");
                }
            });
            Dis.StopInv(deviceNo);

        }

        private void txtBarCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (txtBarCode.Text.Length != config.barcode_len)
                return;

                //if (e.KeyCode == Keys.Enter)//13
            {
                txtBarCode.SelectAll();
                txtEpc.Text = "";
                listUdp.Items.Clear();
                SetState(lblUpd);
                if (txtBarCode.Text.Length != config.barcode_len)
                {
                    SetState(lblUpd);
                    rlog.LogMessage($"二维码长度不等于{config.barcode_len}位,请重新扫描");
                    return;
                }
                ////开始读取标签 
                Dis.StopInv(deviceNo);
                Dis.BeginMultiInv(deviceNo, f);

                //byte[] outData = new byte[64];
                //byte[] antNo = new byte[4];
                ////byte[] res = new byte[14]; // 传给HandleData函数的结果集
                //byte[] res = new byte[64]; // 传给HandleData函数的结果集
                //int dv = 0;
                //Dis.GetSingleParameter(deviceNo, 0x64, out dv);// 第一个字节是设备号
                //res[0] = (byte)dv;
                //if (0 != Dis.ReadSingleTag(deviceNo, outData, antNo))
                //{

                //    for (int i = 0; i < outData[0] + 1; i++)
                //    {
                //        res[i] = outData[i];
                //    }
                //    res[outData[0] + 1] = antNo[0];// 最后的字节是天线号
                //                                   //res[outData[0]  设备号
                //    InsertTag(res, outData[0] + 1);
                //}
                //else
                //{
                //    SetState(lblUpd);
                //    rlog.LogError("RFID标签读取失败,请重试!");
                //}
            }
        }

        void InsertTag(byte[] data, int length)
        {
            string epc = "";
            for (int i = 1; i < length - 1; ++i)
            {
                epc += string.Format("{0:X2} ", data[i]);
            }
            txtEpc.Text = epc;
        }

        Config config; RichTextBoxLog rlog; static System.Timers.Timer timUpd;
        private void txtBarCode_Leave(object sender, EventArgs e)
        {
            txtBarCode.Focus();//定位 
        }
        private Config InitConfig()
        {
            //读取配置
            try
            {
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Reader.SFC.json");
                if (!File.Exists(path))
                {
                    rlog.LogMessage("Reader.SFC.json文件不存在!");
                    return null;
                }
                else
                {
                    //读取json文件
                    string json = "";
                    using (System.IO.StreamReader sr = new System.IO.StreamReader(path))
                    {
                        json = sr.ReadToEnd();
                    }
                    Config config = json.FromJson<Config>();
                    return config;

                }
            }
            catch (Exception ex)
            {
                rlog.LogError($"InitConfig.Error={ex.Message}");
                return null;
            }

        }
        private void FrmInit_Load(object sender, EventArgs e)
        {
            bool flag;
            //日志初始化
            if (rlog == null)
                rlog = new RichTextBoxLog(rtxt);
            config = InitConfig();
            if (config == null)
            {
                flag = false;
            }
            else
            {
                if (config.Url1.IsNull())
                {
                    rlog.LogError("请在【设置】中设置URL1地址!");
                    flag = false;
                }
                if (config.Url2.IsNull())
                {
                    rlog.LogError("请在【设置】中设置URL2地址!");
                    flag = false;
                }
                if (config.Port.IsNull())
                {
                    rlog.LogError("请在【设置】中设置端口号!");
                    flag = false;
                }
                if (config.host_id.IsNull())
                {
                    rlog.LogError("请在【设置】中设置机台码!");
                    flag = false;
                }

                this.Text = config.AppName + " " + config.Version;

                lblMachineID.Text = config.host_id;
                lblPort.Text = config.Port;

                if (timUpd == null)
                {
                    timUpd = new System.Timers.Timer(config.ReadOverTime);
                }
                else
                {
                    timUpd.Interval = config.ReadOverTime;
                }
                //timUpd.Elapsed += TimUpd_Elapsed;
                // PostTag += FrmReader_PostTag;

                flag = true;
            }
            //RFID设备连接状态
            if (flag && !InitReader())
            {
                flag = false;
            }
            SetState(lblUpd);
            txtBarCode.Focus();
            gscan.Text = $"扫描二维码({config.barcode_len}位)";

            UpdateControls = new UpdateControlEventHandlers(UdpTextEPC);  //订阅UpdateControl事件

        }



        bool bConnected = false; // 连接标志，由委托的异步线程改写




        private bool InitReader()
        {
            try
            {
                this.txtEpc.ReadOnly = true;
                this.btnTest.Visible = false;
                if (config.Port.IsNull())
                {
                    rlog.LogError("请在【设置】中设置端口号!");
                    return false;
                }
                byte[] ip = new byte[32];
                int CommPort = 0;
                int PortOrBaudRate = 9600;
                CommPort = int.Parse(config.Port.Trim("COM".ToCharArray()));


                // 使用委托异步线程执行连接，同时启动定时器，等待
                DeleConnectDev dcd = new DeleConnectDev(ConnectDevice);
                dcd.BeginInvoke(ip, CommPort, PortOrBaudRate, null, null);
                bConnected = false;
                timerConnect.Interval = 3000; // 等待3秒时间
                timerConnect.Tick += TimerConnect_Tick;
                timerConnect.Start();


            }
            catch (Exception ex)
            {
                SetState(lblRfid);
                rlog.LogError($"启动异常:{ex.Message}");
                return false;
            }
            return true;
        }

        private void SerialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

        }

        private void TimerConnect_Tick(object sender, EventArgs e)
        {
            if (!bConnected)
            {
                //labelVersion.Text = rm.GetString("strMsgConnectFailure");
                timerConnect.Stop();
            }
        }
        // 定时器函数，在指定时间内没有完成连接，则执行此函数 
        private void SetState(Label lbl, string msg = "NG")
        {
            UpdateUI.UpdateUIControl(lbl, () =>
            {
                if (msg == "NG")
                {
                    lbl.BackColor = System.Drawing.Color.Salmon;
                }
                else
                {
                    lbl.BackColor = System.Drawing.Color.YellowGreen;
                }
                lbl.Text = msg;
            });

        }
        // 委托执行的连接函数，成功后修改标志并停止定时器
        private void ConnectDevice(byte[] ip, int CommPort, int PortOrBaudRate)
        {
            if (0 == Dis.DeviceInit(ip, CommPort, PortOrBaudRate))
            {

                return;
            }
            if (0 == Dis.DeviceConnect())
            {
                return;
            }
            for (int i = 0; i < 3; ++i)
            { Dis.StopWork(deviceNo); }
            int mainVer = 0, minSer = 0;
            Dis.GetDeviceVersion(deviceNo, out mainVer, out minSer);
            if (mainVer == 0 && minSer == 0)
            {
                //labelVersion.Text = rm.GetString("strMsgInitFailure");
                //btnConnect.Enabled = true;
                //btnDisconnect.Enabled = false;

                UpdateUI.UpdateUIControl(txtEpc, () =>
                {
                    this.txtEpc.ReadOnly = false;
                    this.btnTest.Visible = true;
                    this.txtBarCode.Leave -= new System.EventHandler(this.txtBarCode_Leave);
                    this.txtEpc.TextChanged -= new System.EventHandler(this.txtEpc_TextChanged);
                });
                SetState(lblRfid);
                rlog.LogMessage("初始化失败!");
            }
            else
            {
                //labelVersion.Text = "Version:" + string.Format("{0}.{1}", mainVer, minSer);
                //btnConnect.Enabled = false;
                //btnDisconnect.Enabled = true;
                //btnStartReadData.Enabled = false;
                //btnReadOnce.Enabled = true;
                //rbReadSingleTag.Enabled = true;
                //rbReadMultiTag.Enabled = true;
                //rbReadSingleTag.Checked = true;
                //DisableAccessTagButton(true);
                SetState(lblRfid, "OK");
                rlog.LogMessage("准备就绪!");
                bConnected = true;
                timerConnect.Stop();// 连接成功，结束定时器
            }
        }
        private void TimUpd_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

        }

        private void FrmInit_FormClosing(object sender, FormClosingEventArgs e)
        {
            Dis.ResetReader(deviceNo);
            Dis.DeviceDisconnect();
            Dis.DeviceUninit();
            bConnected = false;
        }
        static int SN = 0;
        string GetSN()
        {
            SN++;
            return (Math.Pow(10, 6).ToString() + SN).ToString().Substring(1);
        }
        private void txtEpc_TextChanged(object sender, EventArgs e)
        {
            if (txtEpc.Text.IsNull()) return;
            string str = string.Empty;
            try
            {
                SFC_Do_Sign bing = new SFC_Do_Sign()
                {
                    request_id = config.host_ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHMMssfff") + GetSN(),
                    host_id = config.host_id,
                    host_ip = config.host_ip,
                    bind_code = new List<BindCode2>(),
                    operation_user = config.operation_user,
                    process_name = config.process_name,
                    rfid = txtEpc.Text.Trim(),
                    wrkst_action = "bing",
                    //wrkst_name = "绑定",
                    wrkst_type = config.wrkst_type,
                    resv1 = "",
                    resv2 = "",
                    resv3 = ""
                };
                bing.bind_code.Add(new BindCode2()
                {
                    sn = txtBarCode.Text.Trim(),
                    sn_type =config.sn_type
                });

                var param = "data=" + bing.ToJson();
#if !DEBUG
                str = HttpHelper.POST(url: config.Url0, param: param, time: 500);//过站确认 
#else
                str = "{\"rc\":\"000\",\"rm\":\"工站類型不匹配,應在焊接制程的綁碼2工站進行掃描\",\"barcode\":\"DR8805600D1MNBCAZ01\",\"barCodeInfo\":{\"BAR_CODE\":\"DR8805600D1MNBCAZ01\",\"BILL_NO\":\"701-1801060F\",\"BILL_CONFIG\":\"CONF\",\"CLIENT_CODE\":\"\",\"PRODUCT_ID\":\"1016034946\",\"PRODUCT_NAME\":\"701\",\"PHASE_ID\":\"2016035006\",\"PHASE_NAME\":\"Proto1\",\"PART_ID\":\"3016035326\",\"PART_NAME\":\"Housing\",\"PROCESS_ID\":\"4017036126\",\"PROCESS_NAME\":\"焊接\"},\"request_id\":\"101735817600000026\"}";
                rlog.LogSuccess(str);
#endif
            }

            catch (Exception ex)
            {

                rlog.LogError("绑码.Error=" + ex.Message);
                SetState(lblUpd);
                return;
            }
            string webRes = "NG";
            if (str.IsNotNull())
            {
                UpdResult udp2 = str.FromJson<UpdResult>();
                webRes = udp2.rc;
                if (udp2.rc != "000")
                {
                    rlog.LogError("过站确认.Error=" + udp2.rm);
                }

            }
            var res = "NG";
            if (webRes == "000") res = "OK";

            this.listUdp.Items.Add(new ListViewItem((this.listUdp.Items.Count + 1).ToString())
            {
                SubItems = {
                      txtBarCode.Text.Trim(),
                      txtEpc.Text.Trim(),
                      config.host_id,
                      res,
                      DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                }
            });
            this.listUdp.Items[this.listUdp.Items.Count - 1].EnsureVisible();

            if (webRes == "000")  //上料确认OK
            {
                SetState(lblUpd, "OK");
            }
            else
            {
                SetState(lblUpd);
                SoundHelper.PlayMySound("error.wav");
                return;
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {

            if (txtEpc.Text.IsNull() || txtBarCode.Text.IsNull()) return;
            string str = string.Empty;
            try
            {
                SFC_Do_Sign bing = new SFC_Do_Sign()
                {
                    request_id = config.host_ip.Replace(".", "") + DateTime.Now.ToString("yyyyMMddHHMMssfff") + GetSN(),
                    host_id = config.host_id,
                    host_ip = config.host_ip,
                    bind_code = new List<BindCode2>(),
                    operation_user = config.operation_user,
                    process_name = config.process_name,
                    rfid = txtEpc.Text.Trim(),
                    wrkst_action = "bing",
                    //wrkst_name = "绑定",
                    wrkst_type = config.wrkst_type,
                    resv1 = "",
                    resv2 = "",
                    resv3 = ""
                };
                bing.bind_code.Add(new BindCode2()
                {
                    sn = txtBarCode.Text.Trim(),
                    sn_type = "prod"
                });

                var param = "data=" + bing.ToJson();
#if !DEBUG
                str = HttpHelper.POST(url: config.Url0, param: param, time: 500);//过站确认 
#else
                str = "{\"rc\":\"000\",\"rm\":\"工站類型不匹配,應在焊接制程的綁碼2工站進行掃描\",\"barcode\":\"DR8805600D1MNBCAZ01\",\"barCodeInfo\":{\"BAR_CODE\":\"DR8805600D1MNBCAZ01\",\"BILL_NO\":\"701-1801060F\",\"BILL_CONFIG\":\"CONF\",\"CLIENT_CODE\":\"\",\"PRODUCT_ID\":\"1016034946\",\"PRODUCT_NAME\":\"701\",\"PHASE_ID\":\"2016035006\",\"PHASE_NAME\":\"Proto1\",\"PART_ID\":\"3016035326\",\"PART_NAME\":\"Housing\",\"PROCESS_ID\":\"4017036126\",\"PROCESS_NAME\":\"焊接\"},\"request_id\":\"101735817600000026\"}";
#endif
                rlog.LogSuccess(str);
            }

            catch (Exception ex)
            {

                rlog.LogError("绑码.Error=" + ex.Message);
                SetState(lblUpd);
                return;
            }
        }
    }
}